import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:xim/common/util/utility.dart';
import 'package:xim/config/route_config.dart';
import 'package:xim/http/apis/message/message_model.dart';
import 'package:xim/widget/dash_chat_2/dash_chat_2.dart';

/// 自定义消息气泡展示样式 [添加箭头]
class MessageRowWidget extends StatelessWidget {
  final ChatMessage message;

  /// 当前用户
  final ChatUser currentUser;
  final MessageOptions messageOptions;
  final ChatMessage? previousMessage;
  final ChatMessage? nextMessage;
  final bool isAfterDateSeparator;
  final bool isBeforeDateSeparator;

  const MessageRowWidget(
      {Key? key,
      required this.message,
      required this.currentUser,
      required this.messageOptions,
      this.previousMessage,
      this.nextMessage,
      required this.isAfterDateSeparator,
      required this.isBeforeDateSeparator})
      : super(key: key);

  @override
  Widget build(BuildContext context) {
    final bool isOwnMessage = message.user.id == currentUser.id;
    bool isPreviousSameAuthor = false;
    bool isNextSameAuthor = false;
    if (previousMessage != null &&
        previousMessage!.user.id == message.user.id) {
      isPreviousSameAuthor = true;
    }
    if (nextMessage != null && nextMessage!.user.id == message.user.id) {
      isNextSameAuthor = true;
    }
    return Container(
      margin: isAfterDateSeparator
          ? EdgeInsets.zero
          : isPreviousSameAuthor
              ? messageOptions.marginSameAuthor
              : messageOptions.marginDifferentAuthor,
      child: Row(
        // 对其用户头像
        crossAxisAlignment: CrossAxisAlignment.start,
        mainAxisAlignment: isOwnMessage ? MainAxisAlignment.end : MainAxisAlignment.start,
        children: [
          if (!isOwnMessage) getAvatar(),
          if (!messageOptions.showOtherUsersAvatar) SizedBox(width: messageOptions.spaceWhenAvatarIsHidden),
          if(isOwnMessage) Container(
            padding: const EdgeInsets.only(right: 4, bottom: 4),
            child: messageStatus,
          ),
          GestureDetector(
              onLongPress: messageOptions.onLongPressMessage != null
                  ? () => messageOptions.onLongPressMessage!(message)
                  : null,
              onTap: messageOptions.onPressMessage != null
                  ? () => messageOptions.onPressMessage!(message)
                  : null,
              child: Column(
                // 消息方向
                crossAxisAlignment: isOwnMessage ? CrossAxisAlignment.end : CrossAxisAlignment.start,
                mainAxisAlignment: MainAxisAlignment.end,
                children: [
                  if (messageOptions.top != null)
                    messageOptions.top!(message, previousMessage, nextMessage),
                  if (!isOwnMessage && messageOptions.showOtherUsersName && (!isPreviousSameAuthor || isAfterDateSeparator))
                    messageOptions.userNameBuilder != null
                        ? messageOptions.userNameBuilder!(message.user)
                        : DefaultUserName(user: message.user),
                  if (message.medias != null && message.medias!.isNotEmpty && messageOptions.textBeforeMedia)
                    messageOptions.messageMediaBuilder != null
                        ? messageOptions.messageMediaBuilder!(message, previousMessage, nextMessage, messageOptions)
                        : MediaContainer(
                            message: message,
                            isOwnMessage: isOwnMessage,
                            messageOptions: messageOptions,
                          ),
                  if (!message.isMediaMessage)
                    // 文本消息展示
                    TextContainer(
                      bubbleDirection: isOwnMessage ? BubbleDirection.right : BubbleDirection.left,
                      messageOptions: messageOptions,
                      message: message,
                      previousMessage: previousMessage,
                      nextMessage: nextMessage,
                      isOwnMessage: isOwnMessage,
                      isNextSameAuthor: isNextSameAuthor,
                      isPreviousSameAuthor: isPreviousSameAuthor,
                      isAfterDateSeparator: isAfterDateSeparator,
                      isBeforeDateSeparator: isBeforeDateSeparator,
                      messageTextBuilder: messageOptions.messageTextBuilder,
                    ),
                  // 媒体消息
                  if (message.isMediaMessage && !messageOptions.textBeforeMedia)
                    messageOptions.messageMediaBuilder != null
                        ? messageOptions.messageMediaBuilder!(
                            message, previousMessage, nextMessage, messageOptions)
                        : MediaContainer(
                            message: message,
                            isOwnMessage: isOwnMessage,
                            messageOptions: messageOptions,
                          ),
                  if (messageOptions.bottom != null)
                    messageOptions.bottom!(message, previousMessage, nextMessage)
                ],
              )
          ),
          if (isOwnMessage) getAvatar(),
          if (!isOwnMessage) Padding(
              padding: const EdgeInsets.only(left: 4, bottom: 4),
              child: messageStatus
          ),
        ],
      ),
    );
  }

  Widget get messageStatus {
    var status = message.status;
    if(status==MessageStatus.pending){
      return const SizedBox(
        height: 12,
        width: 12,
        child: CircularProgressIndicator(strokeWidth: 1.5,)
      );
    }
    if(status==MessageStatus.read){
      return const Text("已读", style: TextStyle(fontSize: 11, color: Colors.grey),);
    }
    if(status==MessageStatus.send){
      return const Text("已发送", style: TextStyle(fontSize: 11, color: Colors.grey),);
    }
    return const SizedBox();
  }

  Widget getAvatar() {
    return messageOptions.avatarBuilder != null
        ? messageOptions.avatarBuilder!(
            message.user,
            messageOptions.onPressAvatar,
            messageOptions.onLongPressAvatar,
          )
        : DefaultAvatar(
            user: message.user,
            onLongPressAvatar: messageOptions.onLongPressAvatar,
            onPressAvatar: messageOptions.onPressAvatar,
          );
  }
}

///方向
enum BubbleDirection { left, right }

class _BubbleClipper extends CustomClipper<Path> {
  final arrowWidth; //箭头宽度
  static const _ArrowHeight = 10.0; //箭头高度
  static const _MinHeight = 32.0; //内容最小高度
  static const _MinWidth = 50.0; //内容最小宽度

  final BubbleDirection direction;
  final Radius radius;

  _BubbleClipper(this.direction, this.radius, {this.arrowWidth = 7.0});

  @override
  Path getClip(Size size) {
    final path = Path();
    final path2 = Path();
    final centerPoint = (size.height / 2).clamp(_MinHeight / 2, _MinHeight / 2);
    if (direction == BubbleDirection.left) {
      //绘制左边三角形
      path.moveTo(0, centerPoint);
      path.lineTo(arrowWidth, centerPoint - _ArrowHeight / 2);
      path.lineTo(arrowWidth, centerPoint + _ArrowHeight / 2);
      path.close();
      //绘制矩形
      path2.addRRect(RRect.fromRectAndRadius(
          Rect.fromLTWH(arrowWidth, 0, (size.width - arrowWidth), size.height),
          radius));
      //合并
      path.addPath(path2, const Offset(0, 0));
    } else {
      //绘制右边三角形
      path.moveTo(size.width, centerPoint);
      path.lineTo(size.width - arrowWidth, centerPoint - _ArrowHeight / 2);
      path.lineTo(size.width - arrowWidth, centerPoint + _ArrowHeight / 2);
      path.close();
      //绘制矩形
      path2.addRRect(RRect.fromRectAndRadius(
          Rect.fromLTWH(0, 0, (size.width - arrowWidth), size.height), radius));
      //合并
      path.addPath(path2, const Offset(0, 0));
    }
    return path;
  }

  @override
  bool shouldReclip(CustomClipper<Path> oldClipper) {
    return false;
  }
}

/// 文本消息·
class TextContainer extends StatelessWidget {
  const TextContainer({
    required this.message,
    this.messageOptions = const MessageOptions(),
    this.previousMessage,
    this.nextMessage,
    this.bubbleDirection,
    this.isOwnMessage = false,
    this.isPreviousSameAuthor = false,
    this.isNextSameAuthor = false,
    this.isAfterDateSeparator = false,
    this.isBeforeDateSeparator = false,
    this.messageTextBuilder,
    Key? key,
  }) : super(key: key);

  /// 气泡小箭头方向（默认不显示 null）
  final BubbleDirection? bubbleDirection;

  /// Options to customize the behaviour and design of the messages
  final MessageOptions messageOptions;

  /// Message that contains the text to show
  final ChatMessage message;

  /// Previous message in the list
  final ChatMessage? previousMessage;

  /// Next message in the list
  final ChatMessage? nextMessage;

  /// If the message is from the current user
  final bool isOwnMessage;

  /// If the previous message is from the same author as the current one
  final bool isPreviousSameAuthor;

  /// If the next message is from the same author as the current one
  final bool isNextSameAuthor;

  /// If the message is preceded by a date separator
  final bool isAfterDateSeparator;

  /// If the message is before by a date separator
  final bool isBeforeDateSeparator;

  /// We could acces that from messageOptions but we want to reuse this widget
  /// for media and be able to override the text builder
  final Widget Function(ChatMessage, ChatMessage?, ChatMessage?)?
      messageTextBuilder;

  @override
  Widget build(BuildContext context) {
    var arrowWidth = 7.0;
    var borderRadius = messageOptions.borderRadius;
    // 绘制菜单框
    return bubbleDirection != null
        ? ClipPath(
            clipper: _BubbleClipper(
                bubbleDirection!, Radius.circular(borderRadius),
                arrowWidth: arrowWidth),
            child: messageBubble(context,
                arrowWidth: arrowWidth, bubbleDirection: bubbleDirection!),
          )
        : messageBubble(context);
  }

  /// 消息主体
  Widget messageBubble(BuildContext context,
      {double arrowWidth = 0,
      BubbleDirection bubbleDirection = BubbleDirection.right}) {
    var messagePadding = messageOptions.messagePadding;
    if (arrowWidth != 0) {
      switch (bubbleDirection) {
        case BubbleDirection.left:
          messagePadding = EdgeInsets.only(
              top: messagePadding.top,
              bottom: messagePadding.bottom,
              right: messagePadding.right,
              left: messagePadding.left + arrowWidth);
          break;
        case BubbleDirection.right:
          messagePadding = EdgeInsets.only(
              top: messagePadding.top,
              bottom: messagePadding.bottom,
              right: messagePadding.right + arrowWidth,
              left: messagePadding.left);
          break;
      }
    }
    // TODO 需求待完成： 默认长按时全选
    // var selectAll = message.customProperties?['selectAll'] == true;
    var selectAll = true;
    // EdgeInsets.symmetric();
    return Container(
      decoration: messageOptions.messageDecorationBuilder != null
          ? messageOptions.messageDecorationBuilder!(
              message, previousMessage, nextMessage)
          : defaultMessageDecoration(
              color: isOwnMessage
                  ? messageOptions.currentUserContainerColor(context)
                  : messageOptions.containerColor,
              borderTopLeft:
                  isPreviousSameAuthor && !isOwnMessage && !isAfterDateSeparator
                      ? messageOptions.borderRadius
                      : messageOptions.borderRadius,
              borderTopRight:
                  isPreviousSameAuthor && isOwnMessage && !isAfterDateSeparator
                      ? messageOptions.borderRadius
                      : messageOptions.borderRadius,
              borderBottomLeft:
                  !isOwnMessage && !isBeforeDateSeparator && isNextSameAuthor
                      ? messageOptions.borderRadius
                      : messageOptions.borderRadius,
              borderBottomRight:
                  isOwnMessage && !isBeforeDateSeparator && isNextSameAuthor
                      ? messageOptions.borderRadius
                      : messageOptions.borderRadius,
            ),
      padding: messagePadding,
      child: ConstrainedBox(
        constraints: BoxConstraints(maxWidth: 0.6.sw),
        child: selectAll?SelectableText(
          message.text,
          showCursor: false,
          cursorWidth: 6,
          contextMenuBuilder: _buildContextMenu,
          style: TextStyle(
            color: isOwnMessage
                ? messageOptions.currentUserTextColor(context)
                : messageOptions.textColor,
          ),
        ):Text(
            message.text,
            style: TextStyle(
              color: isOwnMessage
                  ? messageOptions.currentUserTextColor(context)
                  : messageOptions.textColor,
            )
        ),
      ),
    );
  }

  Widget _buildContextMenu(BuildContext context, EditableTextState state){
    final TextEditingValue value = state.textEditingValue;
    String selectValue = value.selection.textInside(value.text);
    final List<ContextMenuButtonItem> buttonItems = [ContextMenuButtonItem(
        label: "复制",
        onPressed: (){
          state.copySelection(SelectionChangedCause.toolbar);
          Utility.showToast("已复制");
        }
    )];
    if(value.text != selectValue){
      buttonItems.add(ContextMenuButtonItem(
          label: "全选",
          type: ContextMenuButtonType.selectAll,
          onPressed: (){
            state.selectAll(SelectionChangedCause.toolbar);
          }
      ));
    }
    if(value.text == selectValue){
      buttonItems.add(ContextMenuButtonItem(
        label: "详情",
        onPressed: (){
          var id = message.messageId;
          Routers.toMessageDetailPage(id);
        }
      ));
      buttonItems.add(ContextMenuButtonItem(
          label: "删除",
          onPressed: (){

          }
      ));
      buttonItems.add(ContextMenuButtonItem(
          label: "回复",
          onPressed: (){
          }
      ));

    }
    return AdaptiveTextSelectionToolbar.buttonItems(
      anchors: state.contextMenuAnchors,
      buttonItems: buttonItems,
    );
  }
}
